(function (window) {
  const PENDING = 'Pending'
  const FULFILLED = 'Fufilled'
  const REJECTED = 'Rejected'

  /**
   * 自定义Promise
   * @param {funtion} excutor 执行器函数（同步）
   */
  function Promise(excutor) {
    const that = this
    that.state = PENDING // 状态
    that.value = undefined // 成功的返回值
    that.reason = undefined // 失败的原因
    that.resolvedCallbacks = [] // 成功回调队列
    that.rejectedCallbacks = [] // 失败回调队列

    function resolve(value) {
      if (value instanceof Promise) {
        return value.then(resolve, reject)
      }
      setTimeout(() => {
        if (that.state === PENDING) {
          that.state = FULFILLED
          that.value = value
          that.resolvedCallbacks.forEach(cb => {
            cb(value)
          })
        }
      })
    }

    function reject(reason) {
      setTimeout(() => {
        if (that.state === PENDING) {
          that.state = REJECTED
          that.reason = reason
          that.rejectedCallbacks.forEach(cb => {
            cb(reason)
          })
        }
      })
    }

    if (typeof excutor === 'function') {
      try {
        excutor(resolve, reject)
      } catch (error) {
        reject(error)
      }
    }
  }
  /**
   * 指定成功，失败的回调方法
   * 返回一个新的promise
   */
  Promise.prototype.then = function (onFuFilled, onRejected) {
    const that = this
    onFuFilled = typeof onFuFilled === 'function' ? onFuFilled : value => value
    onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err } // 实现异常穿透

    // 返回一个新的promise
    return (promise2 = new Promise((resolve, reject) => {
      /**
       * 指定新promise的回调
       * 根据回调返回结果，改变新promise的状态
       */
      function handleResult(p, callback, data) {
        try {
          const x = callback(data)
          if (p === x) {
            return reject(new TypeError('Error'))
          }

          if (x instanceof Promise) { // 回调结果是promise，根据其then方法拿到返回值，再执行对应回调
            x.then(resolve, reject)
          } else {
            resolve(x)
          }
        } catch (error) {
          reject(error)
        }
      }

      if (that.state === PENDING) { // 如果状态为pending，将回调保存到回调数组
        that.resolvedCallbacks.push(() => { // 成功回调
          handleResult(promise2, onFuFilled, that.value)
        })
        that.rejectedCallbacks.push(() => { // 失败回调
          handleResult(promise2, onRejected, that.reason)
        })
      } else if (that.state === FULFILLED) { // 如果状态为fufilled，异步执行成功回调
        handleResult(promise2, onFuFilled, that.value)
      } else if (that.state === REJECTED) { // 如果状态为reject，异步执行失败回调
        handleResult(promise2, onRejected, that.reason)
      }
    }))
  }

  /**
   * 异常捕捉
   * 返回新promise
   */
  Promise.prototype.catch = function (onRejected) {
    return this.then(undefined, onRejected)
  }

  /**
   * 返回一个指定结果的成功的promise
   */
  Promise.resolve = function (value) {
    return new Promise((resolve, reject) => {
      resolve(value)
    })
  }

  /**
   * 返回一个指定结果的失败的promise
   */
  Promise.reject = function (reason) {
    return new Promise((resolve, reject) => {
      reject(reason)
    })
  }

  Promise.all = function (promises) {
    let fuFilledCount = 0
    let values = []
    return new Promise((resolve, reject) => {
      promises.forEach((p, index) => {
        Promise.resolve(p).then(
          value => {
            fuFilledCount++
            values[index] = value
            if (fuFilledCount === promises.length) {
              resolve(values)
            }
          },
          reason => {
            reject(reason)
          }
        )
      })
    })
  }

  Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
      promises.forEach(p => {
        Promise.resolve(p).then(
          value => {
            resolve(value)
          },
          reason => {
            reject(reason)
          }
        )
      })
    })
  }

  window.Promise = Promise

})(window)